Recursion: 

Example#1: Fibonacci

Positions:	0	1	2	3	4	...
values:		0	1	1	2	3	...

fib(0) = 0 and fib(1) = 1

fib(n) = fib(n-1) + fib(n-2)

Main problem of recursive solution:
fib(3) _ fib(1)

|

fib(2) _ fib(0)

|

fib(1)

n = 30 => Number of recursive calls: approx. 2 million calls
n = 31 => Nb of recursive calls: approx. 4 million
n = 32 => Nb of recursive calls: approx. 7 millions

Time complexity: O(2^n)
Space complexity: O(n)

Solution: Dynamic programming (top-down): recursion + caching (memoization)

a) DP top down (n ---> base cases)
b) DP bottom up (base cases ---> n)


int[] arr = new int[1];
foo(arr)

- Product: 

Iterative solution => not accepted
Recursive solution => accepted: time (O(log2(n)) and space O(log2(n))

x^7 = x^(2^2 + 2 + 1) = x^(2^2) * x^2 * x^1

x^5 = x^(2^2 + 0 * 2 + 1) = x^(2^2) * x^1
 










